#!/usr/bin/python
# -*- coding: utf-8 -*-

#为方便以后移植，参数中的 key 一律为字符串格式
import datetime
import math

import geobox
import logging

from google.appengine.ext import db
from google.appengine.api import memcache 
from google.appengine.api import users

import googledatabase
import getcounter
import commonfunction

USER_INFO_ID_COUNT_NAME = 'UserInfoIDCount'
MICROBLOG_ID_COUNT_NAME = 'MicroblogIDCount'
TAG_ID_COUNT_NAME = 'TagIDCount'
CLOUD_ID_COUNT_NAME = 'CloudIDCount'




COLLECT_ID_COUNT_NAME = 'CollectIDCount'



#-------------------------地图常量---------------------
RADIUS = 6378100

GEOBOX_CONFIGS = (
  (4, 5, True),
  (3, 2, True),
  (3, 8, False),
  (3, 16, False),
  (2, 5, False),
)

def GetGeoBoxList(Latitude, Longitude):
    AllBoxes = []
    for (resolution, slice, use_set) in GEOBOX_CONFIGS:
        if use_set:
            AllBoxes.extend(geobox.compute_set(Latitude, Longitude, resolution, slice))
        else:
            AllBoxes.append(geobox.compute(Latitude, Longitude, resolution, slice))

    return AllBoxes;


def AccountEarthDistance(lat1, lon1, lat2, lon2):
  lat1, lon1 = math.radians(float(lat1)), math.radians(float(lon1))
  lat2, lon2 = math.radians(float(lat2)), math.radians(float(lon2))
  return RADIUS * math.acos(math.sin(lat1) * math.sin(lat2) +
      math.cos(lat1) * math.cos(lat2) * math.cos(lon2 - lon1))

#MaxResults 最多返回个数
#MinParams 最少参数个数   ？不知作用
#注意，返回的不是记录集，而是 LoginName 对应的 UserItem 的字典
def GetNearbyUser(Latitude, Longitude, MaxResults=500, MinParams=(2,0)):
    FoundUser = {}
    for Params in GEOBOX_CONFIGS:
        if len(FoundUser) >= MaxResults:
            break
        if Params < MinParams:
            break

        resolution, slice, unused = Params
        Box = geobox.compute(Latitude, Longitude, resolution, slice)
#        logging.error("--------------GetNearbyUser for box=%s at resolution=%s, slice=%s", Box, resolution, slice)
        
        Query = db.GqlQuery( 'SELECT * FROM CUserTable WHERE GeoBoxes = :1', Box)
        Results = Query.fetch(50)
    
#        logging.error("--------------------GetNearbyUser Found %d results", len(Results))

        # De-dupe results.
        for UserItem in Results:
            if UserItem.LoginName not in FoundUser:
                FoundUser[UserItem.LoginName] = UserItem

    return FoundUser


#===================================== 公共 =============================================

#分页、按ID反向 获得一个表的内容    
#返回： 结果集, 前一页起始TagID, 后一页起始TagID
def GetOneTableRecordAtPage(TableName, PageSize, TagID = '', Where = ''):
    if 1 > len(TableName):
        return None
    
    #只有最新的、第一页才放入缓存
    CatchRecordName = TableName + '_New'
    CatchPrePageName = TableName + '_PrePage'
    CatchNextPageName = TableName + '_NextPage'
    if 1 > len(TagID):
        CatchRecord = memcache.get(CatchRecordName)
        if CatchRecord != None:
#            logging.debug("--------------------- CatchRecord != None")
            return CatchRecord, memcache.get(CatchPrePageName), memcache.get(CatchNextPageName)

    #计算上一页起始ID
    PrePageTag = ''
    if 0 < len(TagID):
        Query = db.GqlQuery( 'SELECT * FROM %s WHERE ID > :1 ORDER BY ID' % (TableName), TagID )
        if 0 < len(Where):
            Query = db.GqlQuery( 'SELECT * FROM %s WHERE %s AND ID > :1 ORDER BY ID' % (TableName, Where), TagID )
            
        Results = Query.fetch(PageSize)
        if Results:
            PrePageTag = str(Results[len(Results) - 1].ID)


    #计算下一页起始ID
    Query = db.GqlQuery( 'SELECT * FROM %s ORDER BY ID DESC' % (TableName) )
    if 0 < len(Where):
        Query = db.GqlQuery( 'SELECT * FROM %s WHERE %s ORDER BY ID DESC' % (TableName, Where) )
        
    if 0 < len(TagID):
        Query = db.GqlQuery( 'SELECT * FROM %s WHERE ID <= :1 ORDER BY ID DESC' % (TableName), TagID )
        if 0 < len(Where):
            Query = db.GqlQuery( 'SELECT * FROM %s WHERE %s AND ID <= :1 ORDER BY ID DESC' % (TableName, Where), TagID )
        
    Results = Query.fetch(PageSize + 1)
    NextPageTag = ''
    if len(Results) == PageSize + 1:
        NextPageTag = str(Results[PageSize].ID)
        Results = Results[:PageSize]

    #只有最新的、第一页才放入缓存
    if 1 > len(TagID) and Results:
        memcache.set(CatchRecordName, Results)
        memcache.set(CatchPrePageName, PrePageTag)
        memcache.set(CatchNextPageName, NextPageTag)

    #logging.debug("--------------------- len(Results) = %d, Results = %s, PrePageTag = %s, NextPageTag = %s", len(Results), Results, PrePageTag, NextPageTag)
    return Results, PrePageTag, NextPageTag





#分页、逆时获得某用户某个表的记录集（函数内转换了朋友的昵称）
#返回： 结果集, 前一页起始TagDate, 后一页起始TagDate
def GetOneUserTableRecordFromDate(TableName, LoginName, PageSize, TimeDelta, TagDate = '', ModifyNickNameFieldList = []):
#    logging.debug( "-------------- GetOneUserTableRecordFromDate 1: TableName = %s, LoginName = %s, TimeDelta = %s, TagDate = %s, ModifyNickName = %d"
#                   % (TableName, LoginName, TimeDelta, TagDate, ModifyNickName) )
    #计算上一页起始ID
    PrePageTag = ''
    if 0 < len(TagDate):
        Query = db.GqlQuery( 'SELECT * FROM %s WHERE LoginName = :1 AND Date > :2 ORDER BY Date' % (TableName),
                             LoginName, commonfunction.GetDatetimeFromString(TagDate) )
        Results = Query.fetch(PageSize)
        if Results:
            PrePageTag = str(Results[len(Results) - 1].Date)
#    logging.debug( "--------------------- GetOneUserTableRecordFromDate 2: TagDate = %s, PrePageTag = %s" % (TagDate, PrePageTag) )
            
    #计算下一页起始ID
    Query = db.GqlQuery( 'SELECT * FROM %s WHERE LoginName = :1 ORDER BY Date DESC' % (TableName), LoginName )
    if 0 < len(TagDate):
        Query = db.GqlQuery( 'SELECT * FROM %s WHERE LoginName = :1 AND Date <= :2 ORDER BY Date DESC' % (TableName),
                             LoginName, commonfunction.GetDatetimeFromString(TagDate) )
    Results = Query.fetch(PageSize + 1)
#    logging.debug( "--------------------- GetOneUserTableRecordFromDate 3: len(Results) = %d" % (len(Results)) )
    
    NextPageTag = ''
    if len(Results) == PageSize + 1:
        NextPageTag = str(Results[PageSize].Date)
        Results = Results[:PageSize]

    #修正用户昵称
    for Item in Results:
#        logging.error( "--------------------- GetOneUserTableRecordFromDate 4: ModifyNickName = %d, Item.LoginName = %s" % (ModifyNickName, Item.LoginName) )
        for AttribName in ModifyNickNameFieldList:
            setattr( Item, AttribName, commonfunction.GetOneUserNickName(getattr(Item, AttribName)) )
            if '' == getattr(Item, AttribName):
                setattr( Item, AttribName, commonfunction.GetEmptyNickName(TimeDelta) )
                
        Item.Date += TimeDelta

    return Results, PrePageTag, NextPageTag




#获得某个表的一条记录
def GetOneTableItem(TableName, ItemKeyStr):
    if 1 > len(TableName) or 1 > len(ItemKeyStr):
        return None

#    logging.debug("------------ GetOneTableItem: TableName = %s, ItemKeyStr = %s" % (TableName, ItemKeyStr))
    Query = db.GqlQuery( 'SELECT * FROM %s WHERE __key__ = :1' % (TableName), db.Key(ItemKeyStr) )
    Results = Query.fetch(1)
    if Results:
        return Results[0]
    else:
        return None


#判断一个项目是否在缓存记录集中
def TheItemInMemcacheRecord(CatchRecordName, ItemKeyStr):
    CatchRecord = memcache.get(CatchRecordName)
    if CatchRecord:
        for Item in CatchRecord:
            if str(Item.key()) == ItemKeyStr:
                return True

    return False


#获得一个表的倒数第N的记录
def GetReciprocalItem(TableName, ReciprocalNumber, ColName = 'Date'):
    Query = db.GqlQuery( 'SELECT * FROM %s ORDER BY %s DESC' % (TableName, ColName) )
    Results = Query.fetch(ReciprocalNumber)
    if Results:
        Index = ReciprocalNumber - 1
        if len(Results) - 1 < Index:
            Index = len(Results) - 1

        return Results[Index]

    return None


#增加一个计数，若要减少，那么传负值
def AddOnePropertyCount(ItemKey, PropertyName, AddValue):
    Item = db.get(ItemKey)
    if Item:
        setattr(Item, PropertyName, getattr(Item, PropertyName) + AddValue)
        Item.put()


#从数据库获得管理员配置（系统配置）
def GetAdminConfigFromDatabase():
    Query = db.GqlQuery( 'SELECT * FROM CAdminConfig' )
    AdminConfig = Query.get()

    if AdminConfig == None:
        AdminConfig = googledatabase.CAdminConfig()
        AdminConfig.IntegralPreBlog = 2
        AdminConfig.IntegralPreCommentOn = 1
        AdminConfig.IntegralPreJoin = 10
        
        AdminConfig.MicroblogNeedAuditing = 0
        AdminConfig.AnonymousCanCommentON = 0
        AdminConfig.put()
    
    return AdminConfig

def SetAdminConfigFromDatabase(AdminConfig):
    if AdminConfig == None:
        return
    
    AdminConfig.put()


#===================================== 用户 =============================================
def GetOneUserInfo(LoginID):
    Query = db.GqlQuery('SELECT * FROM CUserTable WHERE LoginID = :1', LoginID)
    return Query.get()


def GetOneUserInfo(LoginName):
    Query = db.GqlQuery('SELECT * FROM CUserTable WHERE LoginName = :1', LoginName)
    return Query.get()


def GetOneUserInfoFromNickName(NickName):
    Query = db.GqlQuery('SELECT * FROM CUserTable WHERE NickName = :1', NickName)
    return Query.get()


def GetOneUserInfoFromLoginOrNickName(LoginOrNickName, LoginFirst = True):
    UserInfo = None
    if LoginFirst:
        UserInfo = GetOneUserInfo(LoginOrNickName)
        if UserInfo == None:
            UserInfo = GetOneUserInfoFromNickName(LoginOrNickName)
    else:
        UserInfo = GetOneUserInfoFromNickName(LoginOrNickName)
        if UserInfo == None:
            UserInfo = GetOneUserInfo(LoginOrNickName)

    return UserInfo


def GetOneUserLoginNameFromLoginOrNickName(LoginOrNickName, LoginFirst = True):
    UserInfo = GetOneUserInfoFromLoginOrNickName(LoginOrNickName)
    LoginName = ''
    if UserInfo:
        LoginName = UserInfo.LoginName
        if LoginName == None:
            LoginName = ''

    return LoginName



def SetOneUserInfo(UserInfo):
    UserInfo.put()

    if TheItemInMemcacheRecord( 'CUserTable_New', str(UserInfo.key()) ):
        #清理缓存区数据
        memcache.delete('CUserTable_New')
        memcache.delete('CUserTable_PrePage')
        memcache.delete('CUserTable_NextPage')


#检查一个NickName是否已存在
def CheckNickNameIsExist(NickName, LoginName = ''):
    Query = db.GqlQuery('SELECT * FROM CUserTable WHERE NickName = :1', NickName)
    if 0 < len(LoginName):
        Query = db.GqlQuery('SELECT * FROM CUserTable WHERE NickName = :1 AND LoginName != :2', NickName, LoginName)

    Results = Query.fetch(1)
    if Results:
        return True
    else:
        return False


#增加一个用户
def AddCurrentUserToUserTable(Language = ''):
    User = users.get_current_user()
    if User is None:
        return

    UserInfo = googledatabase.CUserTable()
    UserInfo.ID = getcounter.GetAutoIncrementCount(USER_INFO_ID_COUNT_NAME)
    UserInfo.LoginName = User.nickname()
    UserInfo.LoginEmail = User.email()
    UserInfo.LoginID = User.user_id()
    UserInfo.Language = Language
    UserInfo.put()

    #清理缓存区数据
    memcache.delete('CUserTable_New')
    memcache.delete('CUserTable_PrePage')
    memcache.delete('CUserTable_NextPage')


#增加一个用户的积分        
def AddOneUserIntegral(LoginName, AddIntegral):
    UserInfo = GetOneUserInfo(LoginName)
    if UserInfo:
        UserInfo.Integral += AddIntegral
        UserInfo.put()

    
def GetHotUserRecord(PageSize):
    Query = db.GqlQuery('SELECT * FROM CUserTable ORDER BY Integral DESC')
    return Query.fetch(PageSize)


#检查 FriendLoginName 是否是 UserLoginName 的朋友
def UserIsFriend(UserLoginName, FriendLoginName):
    Query = db.GqlQuery('SELECT * FROM CFriendTable WHERE FriendName = :1 AND LoginName = :2', FriendLoginName, UserLoginName)
    FriendItem = Query.get()
    if FriendItem:
        return True
    else:
        return False
    
    

#===================================== 微博 =============================================

#获得评论最多的微博记录集
#返回： 结果集
def GetHotMicroblogRecord(PageSize):
    Query = db.GqlQuery('SELECT * FROM CMicroblogTable ORDER BY CommentOnNumber DESC')
    return Query.fetch(PageSize)



#分页、逆时获得一个用户的博客内容
#返回： 结果集, 前一页起始TagID, 后一页起始TagID
def GetOneUserMicroblogRecord(UserLoginName, PageSize, TimeDelta, TagID = ''):
    #计算上一页起始ID
    PrePageTag = ''
    if 0 < len(TagID):
        Query = db.GqlQuery( 'SELECT * FROM CMicroblogTable WHERE LoginName = :1 AND ID > :2 ORDER BY ID', UserLoginName, TagID )
        Results = Query.fetch(PageSize)
        if Results:
            PrePageTag = str(Results[len(Results) - 1].ID)

    #计算下一页起始ID
    Query = db.GqlQuery( 'SELECT * FROM CMicroblogTable WHERE LoginName = :1 ORDER BY ID DESC', UserLoginName )
    if 0 < len(TagID):
        Query = db.GqlQuery( 'SELECT * FROM CMicroblogTable WHERE LoginName = :1 AND ID <= :2 ORDER BY ID DESC', UserLoginName, TagID )
    Results = Query.fetch(PageSize + 1)
    NextPageTag = ''
    if len(Results) == PageSize + 1:
        NextPageTag = str(Results[PageSize].ID)
        Results = Results[:PageSize]

    #修正时间和用户昵称
    for Item in Results:
        Item.LoginName = commonfunction.GetOneUserNickName(Item.LoginName)
        Item.Date += TimeDelta

    return Results, PrePageTag, NextPageTag



#分页、顺时获得一条博客的评论内容
#返回： 结果集, 前一页起始TagID, 后一页起始TagID
def GetOneMicroblogCommentOnRecord(MicroblogKey, PageSize, TimeDelta, TagDate = ''):
    #计算上一页起始ID
    PrePageTag = ''
    if 0 < len(TagDate):
        Query = db.GqlQuery( 'SELECT * FROM CMicroblogCommentOnTable WHERE MicroblogTableKey = :1 AND Date < :2 ORDER BY Date DESC',
                             db.Key(MicroblogKey), commonfunction.GetDatetimeFromString(TagDate) )
        Results = Query.fetch(PageSize)
        logging.debug( "--------------------- CommentOnRecord 1: len(Results) = %d" % (len(Results)) )
        if Results:
            PrePageTag = str(Results[len(Results) - 1].Date)
#    logging.debug( "--------------------- CommentOnRecord: TagDate = %s, PrePageTag = %s" % (TagDate, PrePageTag) )
            
    #计算下一页起始ID
    Query = db.GqlQuery( 'SELECT * FROM CMicroblogCommentOnTable WHERE MicroblogTableKey = :1 ORDER BY Date', db.Key(MicroblogKey) )
    if 0 < len(TagDate):
        Query = db.GqlQuery( 'SELECT * FROM CMicroblogCommentOnTable WHERE MicroblogTableKey = :1 AND Date >= :2 ORDER BY Date',
                             db.Key(MicroblogKey), commonfunction.GetDatetimeFromString(TagDate) )
    Results = Query.fetch(PageSize + 1)
#    logging.debug( "--------------------- CommentOnRecord 2: len(Results) = %d" % (len(Results)) )
    NextPageTag = ''
    if len(Results) == PageSize + 1:
        NextPageTag = str(Results[PageSize].Date)
        Results = Results[:PageSize]

    #修正时间和用户昵称
    for Item in Results:
        Item.LoginName = commonfunction.GetOneUserNickName(Item.LoginName)
        if '' == Item.LoginName:
            Item.LoginName = commonfunction.GetEmptyNickName(TimeDelta)
                
        Item.Date += TimeDelta

    return Results, PrePageTag, NextPageTag



#获得一条微博记录
def GetOneMicroblogItem(MicroblogTableKey, TimeDelta):
    if 1 > len(MicroblogTableKey):
        return None

    Query = db.GqlQuery( 'SELECT * FROM CMicroblogTable WHERE __key__ = :1', db.Key(MicroblogTableKey) )
    Results = Query.fetch(1)
    if Results:
        #修正时间和用户昵称
        Results[0].LoginName = commonfunction.GetOneUserNickName(Results[0].LoginName)
        Results[0].Date += TimeDelta
        
        return Results[0]
    else:
        return None
    
    

#添加一条微博 
def AddOneMicroblog(Title, Content, PublicType, SourceUrl = ''):
#    if 1 > len(Title) or 1 > len(Content):
    if 1 > len(Content):
        return
    
    AddMicroblog = googledatabase.CMicroblogTable()
    AddMicroblog.ID = getcounter.GetAutoIncrementCount(MICROBLOG_ID_COUNT_NAME)
    AddMicroblog.Title = Title
    AddMicroblog.Content = Content
    AddMicroblog.PublicType = PublicType
    if 0 < len(SourceUrl):
        AddMicroblog.SourceUrl = SourceUrl
    AddMicroblog.LoginName = commonfunction.GetUserLoginName()
    AddMicroblog.LastCommentOnDate = 0

    AddMicroblog.put()
    
    #清理缓存区数据
    memcache.delete('CMicroblogTable_New')
    memcache.delete('CMicroblogTable_PrePage')
    memcache.delete('CMicroblogTable_NextPage')

    #增加用户积分
    AdminConfig = commonfunction.GetAdminConfig()
    AddOneUserIntegral(AddMicroblog.LoginName, AdminConfig.IntegralPreBlog)
    

#添加一条博客评论
def AddOneMicroblogCommentOn(MicroblogTableKey, Content):
    if 1 > len(Content):
        return 0
    
    Query = db.GqlQuery( 'SELECT * FROM CMicroblogTable WHERE __key__ = :1', db.Key(MicroblogTableKey) )
    Results = Query.fetch(1)
    if Results is None:
        return 0

    AddMicroblogCommentOn = googledatabase.CMicroblogCommentOnTable()
    AddMicroblogCommentOn.MicroblogTableKey = db.Key(MicroblogTableKey)
    AddMicroblogCommentOn.Content = Content
    AddMicroblogCommentOn.LoginName = commonfunction.GetUserLoginName()

    #检查匿名用户的发表权限
    AdminConfig = commonfunction.GetAdminConfig()
    if AdminConfig.AnonymousCanCommentON == 0 or 0 < len(AddMicroblogCommentOn.LoginName):
        AddMicroblogCommentOn.put()

        #增加用户积分
        AddOneUserIntegral(AddMicroblogCommentOn.LoginName, AdminConfig.IntegralPreCommentOn)
    
        Results[0].LastCommentOnDate = datetime.datetime.now()
        Results[0].put()
        db.run_in_transaction(AddOnePropertyCount, Results[0].key(), 'CommentOnNumber', 1) 
    
    return Results[0].CommentOnNumber


#删除一条微博
def DeleteOneMicroblog(DeleteBlogKeyStr):
    Query = db.GqlQuery("SELECT * FROM CMicroblogCommentOnTable WHERE MicroblogTableKey = :1", db.Key(DeleteBlogKeyStr))
    Results = Query.fetch(1000)
    db.delete(Results)

    Query = db.GqlQuery("SELECT * FROM CMicroblogTable WHERE __key__ = :1", db.Key(DeleteBlogKeyStr))
    Results = Query.fetch(1) 
    db.delete(Results)

    if TheItemInMemcacheRecord('CMicroblogTable_New', DeleteBlogKeyStr):
        #清理缓存区数据
        memcache.delete('CMicroblogTable_New')
        memcache.delete('CMicroblogTable_PrePage')
        memcache.delete('CMicroblogTable_NextPage')



#删除一条微博评论
def DeleteOneCommentOn(DeleteCommentOnKeyStr):
    CommentOnItem = GetOneTableItem('CMicroblogCommentOnTable', DeleteCommentOnKeyStr)
    db.run_in_transaction(AddOnePropertyCount, CommentOnItem.MicroblogTableKey.key(), 'CommentOnNumber', -1)
    
    Query = db.GqlQuery("SELECT * FROM CMicroblogCommentOnTable WHERE __key__ = :1", db.Key(DeleteCommentOnKeyStr))
    Results = Query.fetch(1)
    db.delete(Results)





#===================================== 云：推荐、收藏 =============================================
#获得一个标签记录
def GetOneTagItem(TagName):
    if 1 > len(TagName):
        return None

    Query = db.GqlQuery( 'SELECT * FROM CTagTable WHERE TagName_EN = :1 or TagName_CN = :1', TagName )
    return Query.get()

#设置一个标签记录（没有就添加），返回None 或 Key
def SetOneTagItem(TagName_CN, TagName_EN=''):
    OneTag = GetOneTagItem(TagName_CN)
    if None == OneTag:
        OneTag = CTagTable()
        OneTag.ID = getcounter.GetAutoIncrementCount(TAG_ID_COUNT_NAME)
        OneTag.TagName_CN = TagName_CN
        OneTag.TagName_EN = TagName_EN
        return OneTag.put()
    else:
        return OneTag.key()
    

#获得用户推荐最多的云记录集
#返回： 结果集
def GetHotCommendRecord(PageSize):
    Query = db.GqlQuery('SELECT * FROM CCloudTable ORDER BY CommendNumber DESC')
    return Query.fetch(PageSize)


#获得用户收藏最多的云记录集
#返回： 结果集
def GetHotCollectRecord(PageSize):
    Query = db.GqlQuery('SELECT * FROM CCloudTable ORDER BY CollectNumber DESC')
    return Query.fetch(PageSize)


#获得一个云记录
def GetOneCloudItem(SourceUrl):
    if 1 > len(SourceUrl):
        return None

    Query = db.GqlQuery( 'SELECT * FROM CCloudTable WHERE SourceUrl = :1', SourceUrl )
    return Query.get()

def SetOneCloudItem(SourceUrl, Title, TagName_CN, Summary, IsCommend=True):
    User = users.get_current_user()
    if User is None:
        return None

    OneCloud = GetOneCloudTableItem()
    if None == OneCloud:
        OneCloud = CCloudTable()
        OneCloud.ID = getcounter.GetAutoIncrementCount(CLOUD_ID_COUNT_NAME)
        OneCloud.SourceUrl = SourceUrl
        OneCloud.Title = Title
        OneCloud.TagKey = SetOneTagItem(TagName_CN)
        OneCloud.Summary = Summary
        if IsCommend:
            OneCloud.FirstCommend = OneCloud.LastCommend = User.key()
            OneCloud.CommendNumber = 1
        else:
            OneCloud.FirstCollect = OneCloud.LastCollect = User.key()
            OneCloud.CollectNumber = 1

        RetKey = OneCloud.put()
        
        #清理缓存区数据
        memcache.delete('CCloudTable_New')
        memcache.delete('CCloudTable_PrePage')
        memcache.delete('CCloudTable_NextPage')
    
        return RetKey
    else:
        if IsCommend:
            OneCloud.LastCommend = User.key()
            OneCloud.put()
            db.run_in_transaction(AddOnePropertyCount, OneCloud.key(), 'CommendNumber', 1)
        else:
            OneCloud.LastCollect = User.key()
            OneCloud.put()
            db.run_in_transaction(AddOnePropertyCount, OneCloud.key(), 'CollectNumber', 1)
             
        return OneCloud.key()


#分页、逆时获得一个用户的收藏内容
#返回： 结果集, 前一页起始TagID, 后一页起始TagID
def GetOneUserCollectRecord(UserLoginID, PageSize, TimeDelta, TagDate = ''):
    #计算上一页起始ID
    PrePageTag = ''
    if 0 < len(TagDate):
        Query = db.GqlQuery( 'SELECT * FROM CMyCollectTable WHERE LoginID = :1 AND Date > :2 ORDER BY Date',
                             UserLoginID, commonfunction.GetDatetimeFromString(TagDate) )
        Results = Query.fetch(PageSize)
        logging.debug( "--------------------- CollectRecord 1: len(Results) = %d" % (len(Results)) )
        if Results:
            PrePageTag = str(Results[len(Results) - 1].Date)
#    logging.debug( "--------------------- CollectRecord: TagDate = %s, PrePageTag = %s" % (TagDate, PrePageTag) )

    #计算下一页起始ID
    Query = db.GqlQuery( 'SELECT * FROM CMyCollectTable WHERE LoginID = :1 ORDER BY Date DESC', UserLoginID )
    if 0 < len(TagDate):
        Query = db.GqlQuery( 'SELECT * FROM CMyCollectTable WHERE LoginID = :1 AND Date <= :2 ORDER BY Date DESC',
                             UserLoginID, commonfunction.GetDatetimeFromString(TagDate) )
    Results = Query.fetch(PageSize + 1)
#    logging.debug( "--------------------- CollectRecord 2: len(Results) = %d" % (len(Results)) )
    NextPageTag = ''
    if len(Results) == PageSize + 1:
        NextPageTag = str(Results[PageSize].Date)
        Results = Results[:PageSize]

    #修正时间
    for Item in Results:
        Item.Date += TimeDelta

    return Results, PrePageTag, NextPageTag


#分页、顺时获得一个云推荐的评论内容
#返回： 结果集, 前一页起始TagID, 后一页起始TagID
def GetOneCommendCommentOnRecord(SourceUrl, PageSize, TimeDelta, TagDate = ''):
    OneCloud = GetOneCloudItem(SourceUrl)
    if None == OneCloud:
        return None, '', ''
    
    #计算上一页起始ID
    PrePageTag = ''
    if 0 < len(TagDate):
        Query = db.GqlQuery( "SELECT * FROM CMyCommendTable WHERE HaveCommentOn = True AND CloudKey = :1 AND Date < :2 ORDER BY Date DESC",
                             OneCloud.key(), commonfunction.GetDatetimeFromString(TagDate) )
        Results = Query.fetch(PageSize)
        logging.debug( "--------------------- CollectRecord 1: len(Results) = %d" % (len(Results)) )
        if Results:
            PrePageTag = str(Results[len(Results) - 1].Date)
#    logging.debug( "--------------------- CollectRecord: TagDate = %s, PrePageTag = %s" % (TagDate, PrePageTag) )
            
    #计算下一页起始ID
    Query = db.GqlQuery( "SELECT * FROM CMyCommendTable WHERE HaveCommentOn = True AND CloudKey = :1 ORDER BY Date", OneCloud.key() )
    if 0 < len(TagDate):
        Query = db.GqlQuery( "SELECT * FROM CMyCommendTable WHERE HaveCommentOn = True AND CloudKey = :1 AND Date >= :2 ORDER BY Date",
                             OneCloud.key(), commonfunction.GetDatetimeFromString(TagDate) )
    Results = Query.fetch(PageSize + 1)
#    logging.debug( "--------------------- CollectRecord 2: len(Results) = %d" % (len(Results)) )
    NextPageTag = ''
    if len(Results) == PageSize + 1:
        NextPageTag = str(Results[PageSize].Date)
        Results = Results[:PageSize]

    #修正时间
    for Item in Results:
        Item.Date += TimeDelta

    return Results, PrePageTag, NextPageTag


#分页、顺时获得一个云收藏的评论内容
#返回： 结果集, 前一页起始TagID, 后一页起始TagID
def GetOneCollectCommentOnRecord(SourceUrl, PageSize, TimeDelta, TagDate = ''):
    OneCloud = GetOneCloudItem(SourceUrl)
    if None == OneCloud:
        return None, '', ''
    
    #计算上一页起始ID
    PrePageTag = ''
    if 0 < len(TagDate):
        Query = db.GqlQuery( "SELECT * FROM CMyCollectTable WHERE HaveCommentOn = True AND CloudKey = :1 AND Date < :2 ORDER BY Date DESC",
                             OneCloud.key(), commonfunction.GetDatetimeFromString(TagDate) )
        Results = Query.fetch(PageSize)
        logging.debug( "--------------------- CollectRecord 1: len(Results) = %d" % (len(Results)) )
        if Results:
            PrePageTag = str(Results[len(Results) - 1].Date)
#    logging.debug( "--------------------- CollectRecord: TagDate = %s, PrePageTag = %s" % (TagDate, PrePageTag) )
            
    #计算下一页起始ID
    Query = db.GqlQuery( "SELECT * FROM CMyCollectTable WHERE HaveCommentOn = True AND CloudKey = :1 ORDER BY Date", OneCloud.key() )
    if 0 < len(TagDate):
        Query = db.GqlQuery( "SELECT * FROM CMyCollectTable WHERE HaveCommentOn = True AND CloudKey = :1 AND Date >= :2 ORDER BY Date",
                             OneCloud.key(), commonfunction.GetDatetimeFromString(TagDate) )
    Results = Query.fetch(PageSize + 1)
#    logging.debug( "--------------------- CollectRecord 2: len(Results) = %d" % (len(Results)) )
    NextPageTag = ''
    if len(Results) == PageSize + 1:
        NextPageTag = str(Results[PageSize].Date)
        Results = Results[:PageSize]

    #修正时间
    for Item in Results:
        Item.Date += TimeDelta

    return Results, PrePageTag, NextPageTag


def GetOneUserOneCloud(UserLoginID, SourceUrl, IsCommend=True):
    if 1 > len(UserLoginID) or 1 > len(SourceUrl):
        return None
    
    OneCloud = GetOneCloudItem(SourceUrl)
    if None == OneCloud:
        return None

    Query = None
    if IsCommend:
        Query = db.GqlQuery("SELECT * FROM CMyCommendTable WHERE CloudKey = :1 AND LoginID = :2", OneCloud.key(), UserLoginID)
    else:
        Query = db.GqlQuery("SELECT * FROM CMyCollectTable WHERE CloudKey = :1 AND LoginID = :2", OneCloud.key(), UserLoginID)
    return Query.get()

#添加一个推荐或收藏
def AddOneMyCloud(SourceUrl, Title, TagName_CN, Summary, CommentOn, IsCommend = True):
    User = users.get_current_user()
    if User is None:
        return
    
    if None != GetOneUserOneCloud(User.LoginID, SourceUrl, IsCommend):
        return
    
    OneCloud = SetOneCloudItem(SourceUrl, Title, TagName_CN, Summary, IsCommend)
    if IsCommend:
        MyCommend = CMyCommendTable()
        MyCommend.CloudKey = OneCloud.key()
        MyCommend.LoginID = User.LoginID
        MyCommend.LoginAccount = User.key()
        if 0 < len(CommentOn):
            MyCommend.HaveCommentOn = True
            MyCommend.CommentOn = CommentOn
        else:
            MyCommend.HaveCommentOn = False
        
        MyCommend.put()
    else:
        MyCollect = CMyCollectTable()
        MyCollect.CloudKey = OneCloud.key()
        MyCollect.LoginID = User.LoginID
        MyCollect.LoginAccount = User.key()
        if 0 < len(CommentOn):
            MyCollect.HaveCommentOn = True
            MyCollect.CommentOn = CommentOn
        else:
            MyCollect.HaveCommentOn = False
        
        MyCollect.put()
    

def DeleteOneMyCollect(DeleteUrl):
    User = users.get_current_user()
    if User is None:
        return
    
    OneMyCollect == GetOneUserOneCloud(User.LoginID, DeleteUrl, False)
    if None == OneMyCollect:
        return
    
    if OneMyCollect.CloudKey.LastCollect == User:
        OneMyCollect.CloudKey.LastCollect = None
    if OneMyCollect.CloudKey.FirstCollect == User:
        OneMyCollect.CloudKey.FirstCollect = None
        
    db.run_in_transaction(AddOnePropertyCount, OneMyCollect.CloudKey.key(), 'CollectNumber', -1) 
    
    OneMyCollect.delete()
    

#删除一个云，只有管理员才允许
def DeleteOneSystemCloud(DeleteUrl):
    if False == commonfunction.UserIsAdmin():
        return

    OneCloud = GetOneCloudItem(DeleteUrl)
    if None == OneCloud:
        return

    Query = db.GqlQuery("SELECT * FROM CMyCommendTable WHERE CloudKey = :1", OneCloud.key())
    Results = Query.fetch(1000)
    db.delete(Results)

    Query = db.GqlQuery("SELECT * FROM CMyCollectTable WHERE CloudKey = :1", OneCloud.key())
    Results = Query.fetch(1000)
    db.delete(Results)

    DeleteCloudKeyStr = str(OneCloud.key())
    OneCloud.delete()

    if TheItemInMemcacheRecord('CCloudTable_New', DeleteCloudKeyStr):
        #清理缓存区数据
        memcache.delete('CCloudTable_New')
        memcache.delete('CCloudTable_PrePage')
        memcache.delete('CCloudTable_NextPage')




